#include "USERDEF.h"

USERDEF_T* USERDEF_t;
BAK_Attend_Para_t USERDEF_Attend_Para = { 100, 50 };
USERDEF_BCPar_t BCPar_t;						//< duan0924 特例

//************************************
// Method:    	CALCU_SAMA						//< SAMA运算函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	bool							//< 成功：true；失败：false
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	float dt						//< 运算周期
// Parameter: 	bool * DI						//< 数字量输入值数组指针
// Parameter: 	bool * DO						//< 数字量输出值数组指针
// Parameter: 	bool * AI						//< 模拟量输入值数组指针
// Parameter: 	bool * AO						//< 模拟量输出值数组指针
//************************************
bool CALCU_SAMA(USERDEF)(Model_Base_t* arg, float dt, bool* DI, bool* DO, float* AI, float* AO)
{ 
	NAME(USERDEF)* Obj = (NAME(USERDEF)*)arg;
	if (Obj->Base.UserDef_Mod_Info.UserDef_Mod_Type == USERDEF_TYP_C)
	{
		//arg->List_Base.ID == 19468;
		if (false == arg->UserDef_Mod_Info.Calcu_Method(DI, DO, AI, AO, dt, Obj->Par.DigitalPara_Pt, Obj->Par.AnalogPara_Pt, &(Obj->Sta.DigitalSta_Pt), &(Obj->Sta.AnalogSta_Pt), Obj->Par.filename))
			return false;
	}
	else if (Obj->Base.UserDef_Mod_Info.UserDef_Mod_Type == USERDEF_TYP_PY)
	{
		/****************************************/
		/////////////*python参数定义*/////////////
		/****************************************/
		PyObject* pArgs = NULL;
		PyObject* pArgs_Return = NULL;
		PyObject* pAI_List = NULL;
		PyObject* pDI_List = NULL;
		PyObject* pAO_List = NULL;
		PyObject* pDO_List = NULL;
		PyObject* pAnaPara_List = NULL;
		PyObject* pDigPara_List = NULL;
		PyObject* pAnaSta_List = NULL;
		PyObject* pDigSta_List = NULL;
		int i;
		/****************************************/
		///////////*python参数定义结束*///////////
		/****************************************/

		/****************************************/
		////////////////*参数进栈*////////////////
		/****************************************/
		pArgs = PyTuple_New(10);				//< 元组内容不可变，列表内容可变	//< 共10个参数存放在一个元组中
		pAI_List = PyList_New(Obj->Base.IO_Num.AI_Num);
		pAO_List = PyList_New(Obj->Base.IO_Num.AO_Num);
		pDI_List = PyList_New(Obj->Base.IO_Num.DI_Num);
		pDO_List = PyList_New(Obj->Base.IO_Num.DO_Num);
		pAnaPara_List = PyList_New(Obj->Par.AnalogPara_Num);
		pDigPara_List = PyList_New(Obj->Par.DigitalPara_Num);
		pAnaSta_List = PyList_New(Obj->Sta.AnalogSta_Num);
		pDigSta_List = PyList_New(Obj->Sta.DigitalSta_Num);
		//pAI_List = PyList_New(0);				//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//pAO_List = PyList_New(0);				//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//pDI_List = PyList_New(0);				//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//pDO_List = PyList_New(0);				//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//pAnaPara_List = PyList_New(0);		//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//pDigPara_List = PyList_New(0);		//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//pAnaSta_List = PyList_New(0);			//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//pDigSta_List = PyList_New(0);			//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		//< 参数一赋值
		for (i = 0; i < Obj->Base.IO_Num.DI_Num; i++)
		{
			PyList_SetItem(pDI_List, i, Py_BuildValue("b", DI[i]));
			//PyList_Append(pDI_List, Py_BuildValue("b", DI[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 0, pDI_List);
		//< 参数二赋值
		for (i = 0; i < Obj->Base.IO_Num.DO_Num; i++)
		{
			PyList_SetItem(pDO_List, i, Py_BuildValue("b", DO[i]));
			//PyList_Append(pDO_List, Py_BuildValue("b", DO[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 1, pDO_List);
		//< 参数三赋值
		for (i = 0; i < Obj->Base.IO_Num.AI_Num; i++)
		{
			PyList_SetItem(pAI_List, i, Py_BuildValue("f", AI[i]));
			//PyList_Append(pAI_List, Py_BuildValue("f", AI[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 2, pAI_List);
		//< 参数四赋值
		for (i = 0; i < Obj->Base.IO_Num.AO_Num; i++)
		{
			PyList_SetItem(pAO_List, i, Py_BuildValue("f", AO[i]));
			//PyList_Append(pAO_List, Py_BuildValue("f", AO[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 3, pAO_List);
		//< 参数五赋值
		PyTuple_SetItem(pArgs, 4, Py_BuildValue("f", dt));
		//< 参数六赋值
		for (i = 0; i < Obj->Par.DigitalPara_Num; i++)
		{
			PyList_SetItem(pDigPara_List, i, Py_BuildValue("b", Obj->Par.DigitalPara_Pt[i]));
			//PyList_Append(pDigPara_List, Py_BuildValue("b", Obj->Par.DigitalPara_Pt[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 5, pDigPara_List);
		//< 参数七赋值
		for (i = 0; i < Obj->Par.AnalogPara_Num; i++)
		{
			PyList_SetItem(pAnaPara_List, i, Py_BuildValue("f", Obj->Par.AnalogPara_Pt[i]));
			//PyList_Append(pAnaPara_List, Py_BuildValue("f", Obj->Par.AnalogPara_Pt[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 6, pAnaPara_List);
		//< 参数八赋值
		for (i = 0; i < Obj->Sta.DigitalSta_Num; i++)
		{
			PyList_SetItem(pDigSta_List, i, Py_BuildValue("b", Obj->Sta.DigitalSta_Pt[i]));
			//PyList_Append(pDigSta_List, Py_BuildValue("b", Obj->Sta.DigitalSta_Pt[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 7, pDigSta_List);
		//< 参数九赋值
		for (i = 0; i < Obj->Sta.AnalogSta_Num; i++)
		{
			PyList_SetItem(pAnaSta_List, i, Py_BuildValue("f", Obj->Sta.AnalogSta_Pt[i]));
			//PyList_Append(pAnaSta_List, Py_BuildValue("f", Obj->Sta.AnalogSta_Pt[i]));	//< Shike20210513 师兄原先这样的写法有问题！标准的内存泄露写法
		}
		PyTuple_SetItem(pArgs, 8, pAnaSta_List);
		//< ShiKe20201021新增 参数十赋值 文件名字符串
		PyTuple_SetItem(pArgs, 9, Py_BuildValue("s", Obj->Par.filename));
		/****************************************/
		//////////////*参数进栈结束*//////////////
		/****************************************/

		/****************************************/
		////////////////*执行函数*////////////////
		/****************************************/
		pArgs_Return = PyObject_CallObject(Obj->Base.UserDef_Mod_Info.pFunc, pArgs);
		if (pArgs_Return == NULL)
		{
			printf("Calcu Error!Continue to next Step\n");
			Py_DECREF(pAI_List);
			Py_DECREF(pAO_List);
			Py_DECREF(pDI_List);
			Py_DECREF(pDO_List);
			Py_DECREF(pAnaPara_List);
			Py_DECREF(pDigPara_List);
			Py_DECREF(pAnaSta_List);
			Py_DECREF(pDigSta_List);
			Py_DECREF(pArgs);
			return true;
		}
		/****************************************/
		//////////////*执行函数结束*//////////////
		/****************************************/

		/****************************************/
		//////////////*获取运算结果*//////////////
		/****************************************/
		for (i = 0; i < Obj->Base.IO_Num.DO_Num; i++)
		{
			DO[i] = ((PyLong_AsLong(PyList_GetItem(PyTuple_GetItem(pArgs_Return, 0), i)) == 1) ? true : false);
		}
		for (i = 0; i < Obj->Base.IO_Num.AO_Num; i++)
		{
			AO[i] = (float)PyFloat_AsDouble(PyList_GetItem(PyTuple_GetItem(pArgs_Return, 1), i));
		}
		for (i = 0; i < Obj->Sta.DigitalSta_Num; i++)
		{
			Obj->Sta.DigitalSta_Pt[i] = ((PyLong_AsLong(PyList_GetItem(PyTuple_GetItem(pArgs_Return, 2), i)) == 1) ? true : false);
		}
		for (i = 0; i < Obj->Sta.AnalogSta_Num; i++)
		{
			Obj->Sta.AnalogSta_Pt[i] = (float)PyFloat_AsDouble(PyList_GetItem(PyTuple_GetItem(pArgs_Return, 3), i));
		}
		/****************************************/
		////////////*获取运算结果结束*////////////
		/****************************************/

		/****************************************/
		////////////////*释放内存*////////////////
		/****************************************/
		Py_DECREF(pAI_List);
		Py_DECREF(pAO_List);
		Py_DECREF(pDI_List);
		Py_DECREF(pDO_List);
		Py_DECREF(pAnaPara_List);
		Py_DECREF(pDigPara_List);
		Py_DECREF(pAnaSta_List);
		Py_DECREF(pDigSta_List);
		Py_DECREF(pArgs);
		Py_DECREF(pArgs_Return);
		/****************************************/
		//////////////*释放内存结束*//////////////
		/****************************************/
	}

	return true;
}

//************************************
// Method:    	BCPARA							//< 广播SAMA参数变量函数（无参数需要广播的模块直接将BCPara函数设置为NULL即可）
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int								//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	void ** Data					//< 广播SAMA参数的数据包的指针
//************************************
int BC_PARA(USERDEF)(Model_Base_t* arg, void** Data)
{
#define DigitalPar_Num (Obj->Par.DigitalPara_Num)
#define AnalogPar_Num  (Obj->Par.AnalogPara_Num)	
	int _iLen = 0;
	int i = 0;
	NAME(USERDEF)* Obj = (NAME(USERDEF)*)arg;
	
	BCPar_t.DInum = DigitalPar_Num;
	BCPar_t.AInum = AnalogPar_Num;
	
	for (i = 0; i < DigitalPar_Num; i++)
		BCPar_t.DIdata[i] = Obj->Par.DigitalPara_Pt[i];
	for (i = 0; i < AnalogPar_Num; i++)
		BCPar_t.AIdata[i] = Obj->Par.AnalogPara_Pt[i];

	MEMWRITE(BCPar_t, Data[0]);

	return _iLen;

#undef DigitalPar_Num
#undef AnalogPar_Num



//#define DigitalPar_Num (Obj->Par.DigitalPara_Num)
//#define AnalogPar_Num  (Obj->Par.AnalogPara_Num)	
//
//	MEMWRITE(DigitalPar_Num, Data[0]);
//	MEMWRITE(AnalogPar_Num, Data[0]);
//
//	for (i = 0; i < DigitalPar_Num; i++)
//		MEMWRITE(Obj->Par.DigitalPara_Pt[i], Data[0]);
//		
//	for (i = 0; i < AnalogPar_Num; i++)
//		MEMWRITE(Obj->Par.AnalogPara_Pt[i], Data[0]);
//	
//	return _iLen;
//
//#undef DigitalPar_Num
//#undef AnalogPar_Num



}

//************************************
// Method:    	CHANGE_PAR				//< 在线修改模块参数函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int						//< 读取字节长度计数值
// Parameter: 	Model_Base_t* arg		//< 指定模块类型链表的指针
// Parameter: 	void** Data				//< 存放数据包当前指针位置的地址
//************************************
int CHANGE_PAR(USERDEF)(Model_Base_t* arg, void** Data)
{
	int _iLen = 0;
	int i;

	NAME(USERDEF)* Obj = (NAME(USERDEF)*)arg;

	MEMREAD(Obj->Par.DigitalPara_Num, Data[0]);
	MEMREAD(Obj->Par.AnalogPara_Num, Data[0]);

	FREE_Pt(Obj->Par.DigitalPara_Pt);
	FREE_Pt(Obj->Par.AnalogPara_Pt);

	Obj->Par.DigitalPara_Pt = (bool*)calloc(Obj->Par.DigitalPara_Num, sizeof(bool));
	Obj->Par.AnalogPara_Pt = (float*)calloc(Obj->Par.AnalogPara_Num, sizeof(float));

	for(i = 0; i < Obj->Par.DigitalPara_Num; i++)
	{
		MEMREAD(Obj->Par.DigitalPara_Pt[i], Data[0]);
	}
	for (i = 0; i < Obj->Par.AnalogPara_Num; i++)
	{
		MEMREAD(Obj->Par.AnalogPara_Pt[i], Data[0]);
	}
	//if (Obj->Base.UserDef_Mod_Info.UserDef_Mod_Type == USERDEF_TYP_PY)	////<ShiKe20201021 新增python算法块传入一个字符串
	//{
		MEMREAD(Obj->Par.filename, Data[0]);
	//}
	return _iLen;
}

//************************************
// Method:    	BAK_STA							//< 备份SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int								//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 指定模块类型链表的指针
// Parameter: 	void ** Data					//< 存放数据包当前指针位置的地址
//************************************
int BAK_STA(USERDEF)(Model_Base_t* arg, void** Data)
{
	int i;
	int _iLen = 0;
	NAME(USERDEF)* Obj = (NAME(USERDEF)*)arg;
	for (i = 0; i < Obj->Sta.DigitalSta_Num; i++)
	{
		MEMWRITE(Obj->Sta.DigitalSta_Pt[i], Data[0]);
	}
	for (i = 0; i < Obj->Sta.AnalogSta_Num; i++)
	{
		MEMWRITE(Obj->Sta.AnalogSta_Pt[i], Data[0]);
	}
	return _iLen;
}



//************************************
// Method:    	ANA_STA							//< 解析备份的SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int								//< 成功：返回解析字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	void ** Data					//< 存放数据包当前指针位置的地址
//************************************
int ANA_STA(USERDEF)(Model_Base_t* arg, void** Data)
{
	int i;
	int _iLen = 0;
	NAME(USERDEF)* Obj = (NAME(USERDEF)*)arg;
	for (i = 0; i < Obj->Sta.DigitalSta_Num; i++)
	{
		MEMREAD(Obj->Sta.DigitalSta_Pt[i], Data[0]);
	}
	for (i = 0; i < Obj->Sta.AnalogSta_Num; i++)
	{
		MEMREAD(Obj->Sta.AnalogSta_Pt[i], Data[0]);
	}
	return _iLen;
}



//************************************
// Method:    	INIT_STAPAR						//< 初始化模块运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Parameter: 	Model_Base_t* arg				//< 模块参数结构体指针
//************************************
void INIT_STAPAR(USERDEF)(Model_Base_t* arg)
{
	NAME(USERDEF)* name = (NAME(USERDEF)*)arg;
	/****************初始化中间变量结构体**************/
	//< memset(&(name->Sta), 0, sizeof(name->Sta));
	/**************初始化中间变量结构体结束************/

	/****************对中间变量结构体的相关参数进行赋值**************/
	name->Sta.DigitalSta_Pt = (bool*)calloc(name->Sta.DigitalSta_Num, sizeof(bool));
	name->Sta.AnalogSta_Pt = (float*)calloc(name->Sta.AnalogSta_Num, sizeof(float));
	/**************对中间变量结构体的相关参数进行赋值结束************/
}